package com.ym.b2b.payment.controller.ccbPay;

import java.text.SimpleDateFormat;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSON;
import com.ym.b2b.commons.conf.B2BConstants;
import com.ym.b2b.commons.conf.WebTokenUser;
import com.ym.b2b.commons.controller.BaseController;
import com.ym.b2b.commons.exception.BaseException;
import com.ym.b2b.commons.util.CheckData;
import com.ym.b2b.order.DefaultTradeRequestImpl;
import com.ym.b2b.order.TradeRequest;
import com.ym.b2b.order.dao.EmSOrderConfirmItemDao;
import com.ym.b2b.order.dao.EmSOrderDao;
import com.ym.b2b.order.sqlbean.EmSOrder;
import com.ym.b2b.order.sqlbean.EmSOrderConfirmItem;
import com.ym.b2b.order.vo.OrderInfoVO;
import com.ym.b2b.order.xc.sqlbean.XCReturnModel;
import com.ym.b2b.payment.service.EmSPaymentService;
import com.ym.b2b.payment.sqlbean.EmSPayment;
import com.ym.b2b.payment.util.MD5Util;
import com.ym.b2b.payment.vo.PaymentBean;
import com.zc.commons.base.Result;

@Controller
@RequestMapping("/CCBPay")
public class CCBPayController extends BaseController {

	//	密钥公钥
	private static String strPubKey = "30819d300d06092a864886f70d010101050003818b00308187028181009ba4951169c5deecf03a8ddb2fd934f53747c03a211f63bccc84773182bdd8f7159634705041087e4c9053df05326952a143e1aab5e8ba75ed891a91c2db484b66a064abba6605418944d8763814ff23c161101948ec9ef2dfac735b4bb7c7dac18fbf87157b424780eb7080a3e7c9e79dd4841e44a001edfe497b9e3d2181b9020111";
	
	/**
	 * 在cx/config/spring/med-context-bank中配置
	 * 测试时使用 InquiryParam
	 */
    @Resource
    private CCBParam        ccbParamBean;

    @Resource
    private TradeRequest	defaultTradeRequest;
    
    @Autowired
    private EmSOrderDao		emSOrderDao;
    @Autowired
    private EmSOrderConfirmItemDao emSOrderItemDao;
    @Autowired
    private EmSPaymentService	emSPaymentService;

    /**
     * 建行支付
     * 订单列表点在线支付-->立即付款
     */
    @RequestMapping("getCCBPayInfoForFee.s")
    public ModelAndView getCCBPayInfoForFee(EmSOrder emSOrder, HttpServletRequest req) {
        ModelAndView m = new ModelAndView();
        try {
            WebTokenUser token = getWebTokenUser(req);
            if (null == token) {
                m.setViewName(B2BConstants.WEB_NOT_LOGIN);
                return m;
            }
            // 组装需要塞入的订单信息
            EmSOrder s = emSOrderDao.searchOrderDetail(emSOrder);
            if (null == s || s.getStatus() >= 20) {
                m.addObject("info", "订单已经支付过了  不能重复提交!");
                m.setViewName(B2BConstants.WEB_ERROR);
                return m;
            }
            
            CCBParam ccbParam = new CCBParam();
            BeanUtils.copyProperties(ccbParam, ccbParamBean);

            // 填充支付
            PaymentBean emSPaymentBean = new PaymentBean();
            emSPaymentBean.setOrderCode(s.getOrderCode());
            emSPaymentBean.setPaymentRequestIp(CheckData.getIpAddr(req));
            emSPaymentBean.setPaymentMoney(s.getConfirmMoney());
            Result ret = emSPaymentService.doPayBefore(emSPaymentBean);

            if (ret.getCode().equals("100")) {
                m.addObject("info", "订单支付请求 提交失败 请联系管理员!");
                m.setViewName(B2BConstants.WEB_ERROR);
                return m;
            }
            
            ccbParam.setPayment(String.valueOf(s.getConfirmMoney()));
            ccbParam.setOrderId(s.getOrderCode());
            ccbParam.setMac(this.makeMac(ccbParam));
            m.addObject("ccbParam", ccbParam);
            System.out.println("发送到支付网站的数据====CCB \n " + JSON.toJSONString(ccbParam));
            m.setViewName("/center/trade/pay/ccbpay/post_do");
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            m.setViewName(B2BConstants.WEB_ERROR);
        }
        return m;
    }
    
    // 银行返回
    @RequestMapping("recviceCCBPay.s")
    public void recviceCCBPay(CCBParam receiveBean, HttpServletRequest req) {
        try {
            logger.info("接收支付网站回调参数====CCB：" + JSON.toJSONString(receiveBean));
            String recviceStr = makeRecviceStr(receiveBean);
            RSASig rsa=new RSASig();
            rsa.setPublicKey(strPubKey);
            // 验证签名：返回true代表验签成功；否则验签失败。
            boolean verifyResult = rsa.verifySigature(receiveBean.getSign(),recviceStr);
            // 验签成功，还需要判断订单状态，为"Y"表示支付成功。
            boolean paySuccess = verifyResult && receiveBean.getSuccess().equals("Y");

            if (paySuccess) {
                // 更新订单状态 和 支付表数据
                SimpleDateFormat sf = new SimpleDateFormat("yyyyMMDD");

                EmSOrder order = new EmSOrder();
                order.setOrderCode(receiveBean.getOrderId());
                order.setStatus(Double.parseDouble("20"));		// 已付款
                order.setFeeDate(receiveBean.getAccdate());
//                order.setTranSerialNo(receiveBean.getPaymentOrderId());
//                order.setFeeAmount(Double.parseDouble(receiveBean.getPayAmount()) / 100);
                order.setOrderType(1);					//	在线付款

                
                // =========================================	ERP相关处理start	=========================================
                // 在application_config.xml中控制判断什么时候对接ERP下订单 ,false 则在支付后下单, ture则在确认时下单
                if (!DefaultTradeRequestImpl.isBooking()) {
                	// 根据orderCode查出订单信息,订单产品详情,并组装成ERP接口所需model
                	EmSOrder orderForERP = emSOrderDao.searchOrderDetail(order);
                	EmSOrderConfirmItem item = new EmSOrderConfirmItem();
                	item.setOrderCode(receiveBean.getOrderId());
                	List<EmSOrderConfirmItem> listItem = emSOrderItemDao.searchEmSOrderConfirmItem(item);
                	OrderInfoVO vo = makeOrderInfo(orderForERP, listItem);
                	
                	// 调用ERP create接口
                	Result erpResult = defaultTradeRequest.bookingErpOrder(vo,null);
                	if(!"200".equals(erpResult.getCode())){
                		logger.error("ERP下单失败:" + erpResult.getResult());
                		throw new BaseException("ERP下单失败:" + erpResult.getResult());
                	}
                	
                	//*** ERP下单成功：更新erp系统的内部单据号 *******//*
                	XCReturnModel xcReturnModel = (XCReturnModel) erpResult.getData().get("orderRet");
                	if (null != xcReturnModel && !"".equals(xcReturnModel.getOrderCode())) {
                		String returnCode = xcReturnModel.getOrderCode();
                		order.setOrderCodeErp(returnCode.substring(returnCode.indexOf("-")+1) );
                	}
                }else{
                	// 确认订单时已经下订单了,此时修改订单状态为已支付  TODO 接口未提供
                }
                // =========================================	ERP相关处理end	=========================================
                emSOrderDao.updateEmSOrder(order);
                
                EmSPayment payment = new EmSPayment();
                payment.setOrderCode(receiveBean.getOrderId());
                payment.setPaymentFrom("PC");
                payment.setPaymentMedthod("建行");
                payment.setPaymentMoney(Double.parseDouble(receiveBean.getPayment()) / 100);
                payment.setPaymentCompleteDate(sf.parse(receiveBean.getAccdate()));
                payment.setPaymentStatus(1);
                payment.setDealFlag(1);

                emSPaymentService.updateEmSPayment(payment);
                System.out.println("商户订单处理完成");
            } else {
                System.out.println("商户订单处理失败");
            }
            System.out.println("Server接收处理完成"); 
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    private OrderInfoVO makeOrderInfo(EmSOrder orderForERP,List<EmSOrderConfirmItem> list){
    	OrderInfoVO vo = new OrderInfoVO();
    	vo.setOrderCode(orderForERP.getOrderCode());
    	vo.setBuyerCode(orderForERP.getBuyerCode());
    	WebTokenUser user = new WebTokenUser();
    	user.setBuyerCode(orderForERP.getBuyerCode());
    	vo.setUser(user);
    	vo.setSalesman(orderForERP.getSalesman());
    	vo.setEmSOrderConfirmItemList(list);
    	return vo;
    }
    
    private String makeMac(CCBParam ccbParam){
    	StringBuilder sb = new StringBuilder("");
    	sb.append("MERCHANTID=" + ccbParam.getMerchantId());
    	sb.append("&POSID=" + ccbParam.getPosId());
    	sb.append("&BRANCHID=" + ccbParam.getBranchId());
    	sb.append("&ORDERID=" + ccbParam.getOrderId());
    	sb.append("&PAYMENT=" + ccbParam.getPayment());
    	sb.append("&CURCODE=" + ccbParam.getCurCode());
    	sb.append("&TXCODE=" + ccbParam.getTxCode());
    	sb.append("&REMARK1=");
    	if(ccbParam.getRemark1() != null){
    		sb.append(ccbParam.getRemark1().getBytes());
    	}
    	sb.append("&REMARK2=");
    	if(ccbParam.getRemark2() != null){
    		sb.append(ccbParam.getRemark2().getBytes());
    	}
    	sb.append(strPubKey.subSequence(0, 30));
    	return MD5Util.md5(sb.toString());
    }
    
    // 从返回结果取回参与验签的Str
    private String makeRecviceStr(CCBParam ccbParam){
    	StringBuilder sb = new StringBuilder("");
    	sb.append("POSID=" + ccbParam.getPosId());
    	sb.append("&BRANCHID=" + ccbParam.getBranchId());
    	sb.append("&ORDERID=" + ccbParam.getOrderId());
    	sb.append("&PAYMENT=" + ccbParam.getPayment());
    	sb.append("&CURCODE=" + ccbParam.getCurCode());
    	sb.append("&REMARK1=");
    	if(ccbParam.getRemark1() != null){
    		sb.append(ccbParam.getRemark1().getBytes());
    	}
    	sb.append("&REMARK2=");
    	if(ccbParam.getRemark2() != null){
    		sb.append(ccbParam.getRemark2().getBytes());
    	}
    	sb.append("&ACC_TYPE=" + ccbParam.getAcc_type());
    	sb.append("&SUCCESS=" + ccbParam.getSuccess());
    	sb.append("&ACCDATE=" + ccbParam.getAccdate());
    	return sb.toString();
    }
}
